#include "prepare_connection.h"
#include "prepare.h"

using namespace edm::network;

namespace edm{
namespace prepare{

prepare_connection_t::prepare_connection_t(const std::string& host, const std::string& port):
    net_client_t(host, port), m_retry_interval(1), m_retry_counts(0),m_force(false),m_timer(m_io_service)     
{
    logtrace((PREPARE, "prepare_connection_t::prepare_connection_t"));
}


prepare_connection_t::~prepare_connection_t()
{
    logtrace((PREPARE, "prepare_connection_t::~prepare_connection_t begin ..."));
    m_timer.cancel();
    logtrace((PREPARE, "prepare_connection_t::~prepare_connection_t end ok."));
}

void prepare_connection_t::stop(bool force)
{
    logtrace((PREPARE, "prepare_connection_t::stop force:<%s> begin ...", 
              (force?"true":"false")));
    m_force = force;
    if(force)
    {
       m_timer.cancel(); 
    }
    net_client_t::stop();
    logtrace((PREPARE, "prepare_connection_t::stop end ok."));
}

void prepare_connection_t::callback_connect(edm::network::connection_ptr_t c)
{
    logtrace((PREPARE, "prepare_connection_t::callback_connect begin ..."));
    m_retry_counts = 0;
    m_timer.cancel();
    logtrace((PREPARE, "prepare_connection_t::callback_connect end ok."));
}

void prepare_connection_t::callback_error(edm::network::connection_ptr_t c)
{
    logtrace((PREPARE, "prepare_connection_t::callback_error begin ..."));
    if(!m_force)
    {
        m_retry_counts++;
        if(m_retry_counts >= RETRY_LOOP_MAX)
        {
            m_retry_interval = 1;
        }
        else
        {
            m_retry_interval = m_retry_interval*2;
        }

        m_timer.expires_from_now(boost::posix_time::seconds(m_retry_interval));
        m_timer.async_wait(
            boost::bind(&prepare_connection_t::retry_connect, this, c));
    }
    logtrace((PREPARE, "prepare_connection_t::callback_error end ok."));
}

void prepare_connection_t::retry_connect(edm::network::connection_ptr_t c)
{
    logtrace((PREPARE, "prepare_connection_t::retry_connect begin ..."));
    c->start(c->callback_handler(), c->callback_error());
    logtrace((PREPARE, "prepare_connection_t::retry_connect end ok."));
}
    
}}

